<script setup lang="ts">
import { ref, onMounted, nextTick, reactive } from 'vue'
import { useRoute, useRouter} from 'vue-router'
import { useUserStore } from '@/stores/userStore'
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const data = reactive({
  user: {
    username: '',
    password: '',
    phone: '',
    code: '',
  },
  userInfo: {
    username: '',
    password: '',
    repassword: '',
    phone: '',
    email: '',
  },
})

const container = ref<HTMLElement | null>(null)
const mask = ref<HTMLElement | null>(null)
const sflower = ref<HTMLElement | null>(null)
const tabs = ref<HTMLElement[]>([])
const sure = ref<HTMLElement | null>(null)

const tabChange = (el: HTMLElement): void => {
  tabs.value.push(el)
}

const change = (event: any): void => {
  currentIndex.value = tabs.value.indexOf(event.target)
}

const isShow = ref(false)
const isRegister = ref(false)
const currentIndex = ref(0)

let index = 0
let timer: any = 0

const typing = (): void => {
  const content = '我亦无他，惟手熟尔。'
  const containerEl = container.value
  if (index < content.length && containerEl) {
    containerEl.innerHTML = content.slice(0, index++) + '_'
    timer = setTimeout(typing, 100)
  } else if (containerEl) {
    containerEl.innerHTML = content
    clearTimeout(timer)
    isShow.value = true
    containerEl.style.opacity = '0'
  }
}

const goLogin = (): void => {
  tabs.value = []
  isRegister.value = false
  currentIndex.value = 0
  data.userInfo.username = ''
  data.userInfo.password = ''
  data.userInfo.repassword = ''
  data.userInfo.phone = ''
  data.userInfo.email = ''
}

const goRegister = (): void => {
  tabs.value = []
  isRegister.value = true
  currentIndex.value = 0
  data.user.username = ''
  data.user.password = ''
  data.user.phone = ''
  data.user.code = ''
}

const normalLogin = (): void => {
  console.log('正常登录')
  console.log(data.user)
  if (data.user.username.trim() === '' || data.user.password.trim() === '') {
    alert('账号或密码不能为空')
    return
  }
  userStore.getUserInfo(data.user)
}

const phoneLogin = (): void => {
  console.log('手机登录')
  console.log(data.user)
  const sureEL = sure.value
  if (sureEL !== null && !sureEL?.checked) {
    alert('请先同意用户协议')
    return
  }
  if (data.user.phone.trim() === '' || data.user.code.trim() === '') {
    alert('账号或密码不能为空')
    return
  }
}

const register = (): void => {
  const emailRegx = '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$'
  const phoneRegx = '^1[3456789]\d{9}$'
  if (data.userInfo.username.trim() === '') {
    alert('账号或密码不能为空')
    return
  }

  if (data.userInfo.username.length < 6 || data.userInfo.username.length > 12) {
    alert('账号长度为6-12位')
    return
  }

  if (data.userInfo.password.length < 6) {
    alert('密码长度不能小于6位')
    return
  }

  if (data.userInfo.password.trim() === '') {
    return
  }

  if (data.userInfo.repassword.trim() === '') {
    return
  }

  if (data.userInfo.phone.trim() === '') {
    return
  }

  if (data.userInfo.email.trim() === '') {
    return
  }

  if (data.userInfo.password !== data.userInfo.repassword) {
    alert('两次密码不一致')
    return
  }

  if (!data.userInfo.phone.match(phoneRegx)) {
    return
  }

  if (!data.userInfo.email.match(emailRegx)) {
    alert('邮箱格式不正确')
    return
  }
}

const confettiShower: any[] = []
const numConfettis: number = 50
const colors: string[] = ['#f2abe7', '#9fa3ec', '#86d2e1 ', '#fec31e ']

class Confetti {
  x: number = 0
  y: number = 0
  w: number = 0
  h: number = 0
  c: string = ''

  constructor() {
    this.init()
  }

  init() {
    this.w = Math.floor(Math.random() * 10 + 5)
    this.h = this.w * 1
    this.x = Math.floor(Math.random() * 100)
    this.y = Math.floor(Math.random() * 100)
    this.c = colors[Math.floor(Math.random() * colors.length)]
  }
  create() {
    const containerBox = sflower.value
    var newConfetti =
      '<div class="confetti" style="bottom:' +
      this.y +
      '%; left:' +
      this.x +
      '%;width:' +
      this.w +
      'px; height:' +
      this.h +
      'px;"><div class="rotate"><div class="askew" style="background-color:' +
      this.c +
      '"></div></div></div>'
    if (containerBox) {
      containerBox.innerHTML += newConfetti
    }
  }
}

const animateConfetti = (): void => {
  for (var i = 1; i <= numConfettis; i++) {
    var confetti = new Confetti()
    confetti.create()
  }
  var confettis = document.querySelectorAll('.confetti')
  for (var i = 0; i < confettis.length; i++) {
    var opacity = Math.random() + 0.1
    var animated = confettis[i].animate(
      [
        { transform: 'translate3d(0,0,0)', opacity: opacity },
        { transform: 'translate3d(20vw,100vh,0)', opacity: 1 },
      ],
      {
        duration: Math.random() * 3000 + 3000,
        iterations: Infinity,
        delay: -(Math.random() * 5000),
      }
    )

    confettiShower.push(animated)
  }
}

onMounted((): void => {
  // 初始化打字机效果
  nextTick(() => {
    typing()
    animateConfetti()
    if(route.query.model === 'login') {
      isRegister.value = false
    } else {
      isRegister.value = true
    }
  })
})
</script>

<template>
  <div class="login container">
    <div :class="['operate-box', isShow ? 'show' : '']" v-if="!isRegister">
      <div class="tabs">
        <input type="radio" checked name="login" id="message" />
        <label
          for="message"
          :ref="tabChange"
          @click="change($event)"
          class="tab message"
          >短信登录</label
        >
        <input type="radio" name="login" id="username" />
        <label
          for="username"
          :ref="tabChange"
          @click="change($event)"
          class="tab username"
          >账号登录</label
        >
        <input type="radio" name="login" id="qrcode" />
        <label
          for="qrcode"
          :ref="tabChange"
          @click="change($event)"
          class="tab qrcode"
          >扫码登录</label
        >
      </div>
      <div class="flex-wrapper">
        <div class="form-box" v-if="currentIndex === 0">
          <div class="input-box">
            <input
              id="phone"
              type="text"
              required
              autocomplete="off"
              v-model="data.user.phone"
            />
            <label for="phone">手机号</label>
          </div>
          <div class="input-box">
            <input
              id="code"
              type="text"
              required
              autocomplete="off"
              v-model="data.user.code"
            />
            <label for="code">验证码</label>
            <div class="code">发送验证码</div>
          </div>
          <div class="btn-box">
            <p>
              未注册手机号登录时会自动创建新账号，我已阅读并同意
              《用户服务协议》和《隐私政策》
            </p>
            <input type="checkbox" name="" id="sure" ref="sure" />
            <label for="sure" class="tobesure"> </label>
            <button class="btn-login" @click="phoneLogin">登录</button>
          </div>
        </div>
        <div class="form-box" v-if="currentIndex === 1">
          <div class="input-box">
            <input
              id="username"
              type="text"
              required
              autocomplete="off"
              v-model="data.user.username"
            />
            <label for="username">账号/手机号/邮箱</label>
          </div>
          <div class="input-box">
            <input
              id="password"
              type="password"
              required
              autocomplete="off"
              v-model="data.user.password"
            />
            <label for="password">密码</label>
          </div>
          <div class="btn-box">
            <button class="btn-login" @click="normalLogin">登录</button>
          </div>
          <div class="register" @click="goRegister">
            还没账号？<strong>注册一个</strong>
          </div>
          <div class="third-login">
            <div class="other-login">其他登录方式</div>
            <div class="icons">
              <span class="icon iconfont icon-weixin"></span>
              <span class="icon iconfont icon-QQ"></span>
              <span class="icon iconfont icon-weibo"></span>
            </div>
          </div>
        </div>
        <div class="form-box" v-if="currentIndex === 2"></div>
      </div>
    </div>
    <div :class="['operate-box', isShow ? 'show register' : '']" v-else>
      <div class="form-box">
        <div class="input-box">
          <input
            id="username"
            type="text"
            required
            autocomplete="off"
            v-model="data.userInfo.username"
          />
          <label for="username">账号</label>
        </div>
        <div class="input-box">
          <input
            id="password"
            type="text"
            required
            autocomplete="off"
            v-model="data.userInfo.password"
          />
          <label for="password">密码</label>
        </div>
        <div class="input-box">
          <input
            id="repassword"
            type="text"
            required
            autocomplete="off"
            v-model="data.userInfo.repassword"
          />
          <label for="repassword">确认密码</label>
        </div>
        <div class="input-box">
          <input
            id="phone"
            type="text"
            required
            autocomplete="off"
            v-model="data.userInfo.phone"
          />
          <label for="phone">手机号</label>
        </div>
        <div class="input-box">
          <input
            id="email"
            type="text"
            required
            autocomplete="off"
            v-model="data.userInfo.email"
          />
          <label for="email">邮箱</label>
        </div>
        <div class="btn-box" style="margin: 0 0 10px 0">
          <button class="btn-login" @click="register">注册</button>
        </div>
        <div class="register" @click="goLogin">
          已有账号？<strong>去登录</strong>
        </div>
      </div>
    </div>
    <div class="sflower" ref="sflower"></div>
    <div class="typing" ref="container"></div>
    <div :class="['mask', isShow ? 'show' : '']" ref="mask"></div>
  </div>
</template>

<style scoped lang="less">
@property --gradient-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@keyframes rotation {
  0% {
    --gradient-angle: 0deg;
  }
  100% {
    --gradient-angle: 360deg;
  }
}

.login.container {
  position: relative;
  padding: 10px;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  background: url('../../assets/bg.gif') no-repeat;
  background-size: cover;
}

.sflower {
  position: fixed;
  top: -50%;
  left: -50;
  height: 150%;
  width: 100%;
  overflow: hidden;
  z-index: 20;
  pointer-events: none;
  // display: none;
}

.typing {
  position: absolute;
  text-align: center;
  top: 50%;
  left: 50%;
  font-size: 28px;
  letter-spacing: 4px;
  transform: translate(-50%, -50%);
  color: #fff;
  opacity: 1;
  text-shadow: 5px 5px 5px #909090;
  transition: all 0.5s;
}

.mask {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 0;
  height: 0;
  transition: all 0.4s;
}

.show {
  width: 100%;
  height: 100%;
  z-index: 10;
  background-color: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(10px);
}

.operate-box {
  position: fixed;
  box-sizing: border-box;
  width: 300px;
  height: 0%;
  z-index: 100;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  transition: all 0.5s;
  &.show {
    height: 400px;
  }
  &.show.register {
    height: 450px
  }
  .tabs {
    display: flex;
    border-radius: 10px 10px 0 0;
    input {
      display: none;
    }
  }
  .tab {
    padding: 10px;
    flex-grow: 1;
    line-height: 30px;
    font-size: 16px;
    color: #c9c9c9;
    text-align: center;
    background-color: #f5f5f5;
    cursor: pointer;
    transition: all 0.5s;
    &:last-child {
      border-radius: 0 10px 0 0;
    }

    &:nth-of-type(1) {
      border-radius: 10px 0 0 0;
    }

    &.active {
      color: #000;
      font-weight: bold;
      background-color: #fff;
    }
  }
  .form-box {
    box-sizing: border-box;
    width: 100%;
    flex-shrink: 0;
    padding: 10px 20px 20px 20px;
    .input-box {
      display: flex;
      position: relative;
      height: 40px;
      margin: 25px 0 0 0;
      border-radius: 8px;
      .code {
        position: absolute;
        display: block;
        height: 40px;
        right: 6%;
        font-size: 12px;
        cursor: pointer;
        border: none;
        color: aqua;
        line-height: 40px;
        background-color: transparent;
        &::before {
          content: '';
          position: absolute;
          width: 2px;
          height: 30%;
          top: 50%;
          left: -20%;
          transform: translateY(-50%);
          background-color: #d9d9d9;
        }
      }
      label {
        position: absolute;
        left: 15px;
        top: 12px;
        pointer-events: none;
        transition: all 0.5s;
        color: #ccc;
      }
      input {
        display: block;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        outline: none;
        border: none;
        padding: 5px 15px;
        border-radius: 8px;
        font-size: 16px;
        background-color: #f0f0f5;
        box-shadow: inset 0px 1px 5px 0px rgba(0, 0, 0, 0.3);
        &:focus + label,
        &:valid + label {
          top: -20px;
          left: 1%;
          font-size: 12px;
          line-height: 20px;
        }
      }
    }
    .btn-box {
      position: relative;
      width: 100%;
      margin: 20px 0;
      button {
        position: relative;
        display: inline-block;
        width: 100%;
        height: 36px;
        border: none;
        margin-top: 20px;
        border-radius: 10px;
        cursor: pointer;
        color: #fff;
        font-weight: bolder;
        letter-spacing: 4px;
        background: linear-gradient(120deg, #4568dc, #b06ab3);
        &::before,
        &::after {
          content: '';
          position: absolute;
          inset: -0.1rem;
          z-index: -1;
          background: conic-gradient(
            from var(--gradient-angle),
            var(--clr-1),
            var(--clr-2),
            var(--clr-3),
            var(--clr-4),
            var(--clr-5),
            var(--clr-4),
            var(--clr-3),
            var(--clr-2),
            var(--clr-1)
          );
          border-radius: inherit;
          animation: rotation 3s infinite linear;
        }
        &::after {
          filter: blur(2px);
        }
      }
    }
  }
}

#message:checked + .message,
#username:checked + .username,
#qrcode:checked + .qrcode {
  color: #000;
  font-weight: bold;
  background-color: #fff;
}

label.tobesure {
  position: absolute;
  border: 2px solid rgba(132, 133, 141, 0.2);
  box-sizing: border-box;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  cursor: pointer;
  top: 3%;
  left: 0%;
}

#sure {
  display: none;
}

#sure:checked + .tobesure {
  background-color: #637dff;
}

#sure:not(:checked) ~ .btn-login {
  opacity: 1;
  cursor: not-allowed;
}

label.tobesure::after {
  position: absolute;
  content: '';
  border: 2px solid #fff;
  width: 6px;
  height: 3px;
  border-top: none;
  border-right: none;
  transform: translate(-50%, -50%) rotate(-45deg);
  top: 50%;
  left: 50%;
}

p {
  box-sizing: border-box;
  padding-left: 18px;
  width: 100%;
  font-size: 12px;
  line-height: 1.5;
  text-overflow: ellipsis;
  display: -webkit-box;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  position: relative;
}

.third-login {
  font-size: 12px;
  color: #999;
  margin: 10px;
  .other-login {
    text-align: center;
    margin-bottom: 20px;
  }
  .icons {
    display: flex;
    justify-content: space-between;
  }
  .icon {
    display: inline-block;
    width: 30px;
    height: 30px;
    background-color: #637dff;
    border-radius: 50%;
  }
}

.register {
  height: 20px;
  line-height: 20px;
  font-size: 12px;
  text-align: center;
  strong {
    color: #637dff;
    cursor: pointer;
  }
}

.sflower:before,
.sflower:after {
  box-sizing: inherit;
  content: '';
  position: absolute;
}

</style>
